[LINUX] Preserve flags when converting PTEs from machine to phys.
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Tue, 14 Nov 2006 11:57:53 +0000 (11:57 +0000)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Tue, 14 Nov 2006 11:57:53 +0000 (11:57 +0000)
Signed-off-by: John Byrne <john.l.byrne@hp.com>
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/maddr.h
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/maddr.h
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h

index b467320d5ce3f8bd11c19a0b8fec3ba28e186fe1..3916c4ba9eb58b9435269db00e0765c6c76a4704 100644 (file)
@@ -127,6 +127,7 @@ static inline maddr_t phys_to_machine(paddr_t phys)
        machine = (machine << PAGE_SHIFT) | (phys & ~PAGE_MASK);
        return machine;
 }
+
 static inline paddr_t machine_to_phys(maddr_t machine)
 {
        paddr_t phys = mfn_to_pfn(machine >> PAGE_SHIFT);
@@ -134,6 +135,19 @@ static inline paddr_t machine_to_phys(maddr_t machine)
        return phys;
 }
 
+static inline paddr_t pte_machine_to_phys(maddr_t machine)
+{
+       /*
+        * In PAE mode, the NX bit needs to be dealt with in the value
+        * passed to mfn_to_pfn(). On x86_64, we need to mask it off,
+        * but for i386 the conversion to ulong for the argument will
+        * clip it off.
+        */
+       paddr_t phys = mfn_to_pfn(machine >> PAGE_SHIFT);
+       phys = (phys << PAGE_SHIFT) | (machine & ~PHYSICAL_PAGE_MASK);
+       return phys;
+}
+
 /* VIRT <-> MACHINE conversion */
 #define virt_to_machine(v)     (phys_to_machine(__pa(v)))
 #define virt_to_mfn(v)         (pfn_to_mfn(__pa(v) >> PAGE_SHIFT))
index 0f829c8cd3bc7026c84bba8b23372575d7e33086..ff183db39e8739f859a08def6561cda301acec90 100644 (file)
@@ -6,6 +6,16 @@
 #define PAGE_SIZE      (1UL << PAGE_SHIFT)
 #define PAGE_MASK      (~(PAGE_SIZE-1))
 
+#ifdef CONFIG_X86_PAE
+#define __PHYSICAL_MASK_SHIFT  36
+#define __PHYSICAL_MASK                ((1ULL << __PHYSICAL_MASK_SHIFT) - 1)
+#define PHYSICAL_PAGE_MASK     (~((1ULL << PAGE_SHIFT) - 1) & __PHYSICAL_MASK)
+#else
+#define __PHYSICAL_MASK_SHIFT  32
+#define __PHYSICAL_MASK                (~0UL)
+#define PHYSICAL_PAGE_MASK     (PAGE_MASK & __PHYSICAL_MASK)
+#endif
+
 #define LARGE_PAGE_MASK (~(LARGE_PAGE_SIZE-1))
 #define LARGE_PAGE_SIZE (1UL << PMD_SHIFT)
 
@@ -85,7 +95,7 @@ static inline unsigned long long pte_val(pte_t x)
 
        if (x.pte_low) {
                ret = x.pte_low | (unsigned long long)x.pte_high << 32;
-               ret = machine_to_phys(ret) | 1;
+               ret = pte_machine_to_phys(ret) | 1;
        } else {
                ret = 0;
        }
@@ -94,13 +104,13 @@ static inline unsigned long long pte_val(pte_t x)
 static inline unsigned long long pmd_val(pmd_t x)
 {
        unsigned long long ret = x.pmd;
-       if (ret) ret = machine_to_phys(ret) | 1;
+       if (ret) ret = pte_machine_to_phys(ret) | 1;
        return ret;
 }
 static inline unsigned long long pgd_val(pgd_t x)
 {
        unsigned long long ret = x.pgd;
-       if (ret) ret = machine_to_phys(ret) | 1;
+       if (ret) ret = pte_machine_to_phys(ret) | 1;
        return ret;
 }
 static inline unsigned long long pte_val_ma(pte_t x)
@@ -115,7 +125,8 @@ typedef struct { unsigned long pgprot; } pgprot_t;
 #define pgprot_val(x)  ((x).pgprot)
 #include <asm/maddr.h>
 #define boot_pte_t pte_t /* or would you rather have a typedef */
-#define pte_val(x)     (((x).pte_low & 1) ? machine_to_phys((x).pte_low) : \
+#define pte_val(x)     (((x).pte_low & 1) ? \
+                        pte_machine_to_phys((x).pte_low) : \
                         (x).pte_low)
 #define pte_val_ma(x)  ((x).pte_low)
 #define __pte(x) ({ unsigned long _x = (x); \
@@ -125,7 +136,7 @@ typedef struct { unsigned long pgprot; } pgprot_t;
 static inline unsigned long pgd_val(pgd_t x)
 {
        unsigned long ret = x.pgd;
-       if (ret) ret = machine_to_phys(ret) | 1;
+       if (ret) ret = pte_machine_to_phys(ret) | 1;
        return ret;
 }
 #define HPAGE_SHIFT    22
index 0104de80827747bd2b0258df44c3205c455377e9..83e433644988150950be926768bc65f6c30e6417 100644 (file)
@@ -127,6 +127,14 @@ static inline paddr_t machine_to_phys(maddr_t machine)
        return phys;
 }
 
+static inline paddr_t pte_machine_to_phys(maddr_t machine)
+{
+       paddr_t phys;
+       phys = mfn_to_pfn((machine & PHYSICAL_PAGE_MASK) >> PAGE_SHIFT);
+       phys = (phys << PAGE_SHIFT) | (machine & ~PHYSICAL_PAGE_MASK);
+       return phys;
+}
+
 /* VIRT <-> MACHINE conversion */
 #define virt_to_machine(v)     (phys_to_machine(__pa(v)))
 #define virt_to_mfn(v)         (pfn_to_mfn(__pa(v) >> PAGE_SHIFT))
index cd23862b05c1f59bcd9012ff72a344be7682f185..7573cce405f9114b3ac0cc23438c3fde26dcebf4 100644 (file)
 #define PAGE_SIZE      (1UL << PAGE_SHIFT)
 #endif
 #define PAGE_MASK      (~(PAGE_SIZE-1))
+
+/* See Documentation/x86_64/mm.txt for a description of the memory map. */
+#define __PHYSICAL_MASK_SHIFT  46
+#define __PHYSICAL_MASK                ((1UL << __PHYSICAL_MASK_SHIFT) - 1)
+#define __VIRTUAL_MASK_SHIFT   48
+#define __VIRTUAL_MASK         ((1UL << __VIRTUAL_MASK_SHIFT) - 1)
+
 #define PHYSICAL_PAGE_MASK     (~(PAGE_SIZE-1) & __PHYSICAL_MASK)
 
 #define THREAD_ORDER 1 
@@ -90,28 +97,28 @@ typedef struct { unsigned long pgd; } pgd_t;
 
 typedef struct { unsigned long pgprot; } pgprot_t;
 
-#define pte_val(x)     (((x).pte & 1) ? machine_to_phys((x).pte) : \
+#define pte_val(x)     (((x).pte & 1) ? pte_machine_to_phys((x).pte) : \
                         (x).pte)
 #define pte_val_ma(x)  ((x).pte)
 
 static inline unsigned long pmd_val(pmd_t x)
 {
        unsigned long ret = x.pmd;
-       if (ret) ret = machine_to_phys(ret);
+       if (ret) ret = pte_machine_to_phys(ret);
        return ret;
 }
 
 static inline unsigned long pud_val(pud_t x)
 {
        unsigned long ret = x.pud;
-       if (ret) ret = machine_to_phys(ret);
+       if (ret) ret = pte_machine_to_phys(ret);
        return ret;
 }
 
 static inline unsigned long pgd_val(pgd_t x)
 {
        unsigned long ret = x.pgd;
-       if (ret) ret = machine_to_phys(ret);
+       if (ret) ret = pte_machine_to_phys(ret);
        return ret;
 }
 
@@ -163,12 +170,6 @@ static inline pgd_t __pgd(unsigned long x)
 /* to align the pointer to the (next) page boundary */
 #define PAGE_ALIGN(addr)       (((addr)+PAGE_SIZE-1)&PAGE_MASK)
 
-/* See Documentation/x86_64/mm.txt for a description of the memory map. */
-#define __PHYSICAL_MASK_SHIFT  46
-#define __PHYSICAL_MASK                ((1UL << __PHYSICAL_MASK_SHIFT) - 1)
-#define __VIRTUAL_MASK_SHIFT   48
-#define __VIRTUAL_MASK         ((1UL << __VIRTUAL_MASK_SHIFT) - 1)
-
 #define KERNEL_TEXT_SIZE  (40UL*1024*1024)
 #define KERNEL_TEXT_START 0xffffffff80000000UL